package com.mi.rule.generator._0_0_3_联惠商家;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootApplication
public class Generator {

    //TODO 项目路径
    private final static String templates = "_0_0_3";
    private final static String projectPath = System.getProperty("user.dir");

    //TODO 模板文件生成位置
    private final static String createPath = projectPath + "/generator";

    //TODO 代码包结构(根据项目修改（注意结构必须一致）)
    private final static String basePackage = "com.big";//顶层包
    //TODO 文件生成位置
    private final static String controllerPath = createPath + "/module/controller";
    private final static String servicePath = createPath + "/module/service";
    private final static String serviceImplPath = createPath + "/module/service/impl";
    private final static String daoPath = createPath + "/mybatis/gen/dao";
    private final static String entityPath = createPath + "/mybatis/gen/entity";
    private final static String mapperXmlPath = createPath + "/resources/dao/gen";

    //TODO 生成数据
    private final static String excludeTables = null; //排除指定表  "test_table1,test_table2"
    private final static String createTables = "y_yi_lian"; //生成指定表  "test_table1,test_table2"

    //TODO 数据源
    private final static String ip = "127.0.0.1";
    private final static String port = "3306";

    //    private final static String ip = "192.168.247.132";
    //    private final static String port = "3309";
    private final static String databaseName = "big_demo";
    private final static String driverName = "com.mysql.cj.jdbc.Driver";
    private final static String username = "root";
    private final static String password = "1234qwer";
    //    private final static String password = "123456";
    private final static String url = "jdbc:mysql://"
            + ip + ":" + port + "/" + databaseName + "?"
            + "serverTimezone=Asia/Shanghai&characterEncoding=UTF8&"
            + "zeroDateTimeBehavior=convertToNull&useUnicode=true&"
            + "useSSL=false&useTimezone=false";
    private static AutoGenerator generator = null;


    public static void main(String[] args) {
        generator = new AutoGenerator();
        setGlobalConfig();//全局配置
        setDataSource();//数据源配置
        setStrategy();//策略配置
        setPackage();//包配置
        setCfg();//注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
        setTemplate();//模板配置
        generator.execute();
    }

    //全局配置
    private static void setGlobalConfig() {
        generator.setGlobalConfig(
                new GlobalConfig()
                        .setActiveRecord(true)
                        .setOutputDir(createPath)
//                        .setOpen(true)
                        .setOpen(false)
                        .setAuthor("王永吉")
                        .setFileOverride(false)
                        .setEnableCache(false)
                        .setBaseResultMap(false)
                        .setBaseColumnList(false)
                        .setKotlin(false)
                        .setMapperName("%sDao")
//                .setEntityName("%s")
//                .setXmlName("%sMapper")
//                .setServiceName("I%sService")
//                .setServiceImplName("%sServiceImpl")
//                .setControllerName("%sRestController");
        );
    }

    //数据源配置
    private static void setDataSource() {
        generator.setDataSource(
                new DataSourceConfig()
                        .setDbType(DbType.MYSQL)
                        .setDriverName(driverName)
                        .setUrl(url)
                        .setUsername(username)
                        .setPassword(password)
                        //
                        //设置类型转换
                        .setTypeConvert(new MySqlTypeConvert() {
                            @Override
                            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                                if (fieldType.toLowerCase().equals("int")) {
                                    return DbColumnType.INTEGER;
                                }
                                if (fieldType.toLowerCase().equals("varchar")) {
                                    return DbColumnType.STRING;
                                }
                                if (fieldType.toLowerCase().equals("char")) {
                                    return DbColumnType.STRING;
                                }
                                if (fieldType.toLowerCase().equals("longtext")) {
                                    return DbColumnType.STRING;
                                }
                                if (fieldType.toLowerCase().equals("double")) {
                                    return DbColumnType.DOUBLE;
                                }
                                if (fieldType.toLowerCase().equals("decimal")) {
                                    return DbColumnType.BIG_DECIMAL;
                                }
                                if (fieldType.toLowerCase().equals("json")) {
                                    return DbColumnType.STRING;
                                }
                                if (fieldType.toLowerCase().equals("tinyint")) {
                                    return DbColumnType.INTEGER;
                                }
                                if (fieldType.toLowerCase().equals("date")) {
                                    return DbColumnType.LOCAL_DATE;
                                }
                                if (fieldType.toLowerCase().equals("time")) {
                                    return DbColumnType.LOCAL_TIME;
                                }
                                if (fieldType.toLowerCase().equals("datetime")) {
                                    return DbColumnType.LOCAL_DATE_TIME;
                                }
                                if (fieldType.toLowerCase().equals("bigint")) {
                                    return DbColumnType.STRING;
                                }
                                return super.processTypeConvert(globalConfig, fieldType);
                            }
                        })
        );
    }

    //策略配置
    private static void setStrategy() {
        StrategyConfig strategyConfig = new StrategyConfig()
                .setTablePrefix(removeTablePrefix())
                .setFieldPrefix(removeFilePrefix())
                .setEntityBuilderModel(true)
                .setEntityColumnConstant(true)
                .setTableFillList(getTableFills())
                .setEntityTableFieldAnnotationEnable(true)
                .setRestControllerStyle(false)
                .setEntityLombokModel(true)
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel);
        if (createTables != null) {
            strategyConfig.setInclude(createTables.split(","));
        }
        if (excludeTables != null) {
            strategyConfig.setExclude(excludeTables.split(","));
        }
//                        .setSuperMapperClass("com.big.mybatis.base.BaseMapper")

        // strategy.setCapitalMode(true)// 全局大写命名 ORACLE 注意
        //strategy.setSuperControllerClass("com.sample.model.common.BaseController") //指定 顶层 Controller
        //strategy.setSuperEntityClass("com.sample.model.common.BaseEntity") //指定 顶层 实体类
        //strategy.setSuperEntityColumns("id")  //抽出公用 字段
        //strategy.setControllerMappingHyphenStyle(true)    //驼峰 变为  "-"
        generator.setStrategy(strategyConfig);
    }

    //包配置
    private static void setPackage() {
        generator.setPackageInfo(
                new PackageConfig()
                        .setParent("z_z_没用.z_z_没用.z_z_没用.z_z_没用")
                        .setMapper("z_z_没用")
                        .setEntity("z_z_没用")
        );
    }

    //注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
    private static void setCfg() {
        FileOutConfig cMapperXml = new FileOutConfig("/templates" + templates + "/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return mapperXmlPath + "/" + tableInfo.getEntityName() + "Dao" + StringPool.DOT_XML;
            }
        };
        FileOutConfig cDao = new FileOutConfig("/templates" + templates + "/mapper.java.ftl") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                return daoPath + "/" + tableInfo.getEntityName() + "Dao" + StringPool.DOT_JAVA;
            }
        };
        FileOutConfig cController = new FileOutConfig("/templates" + templates + "/controller.java.ftl") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                return controllerPath + "/" + tableInfo.getEntityName() + "Ctr" + StringPool.DOT_JAVA;
            }
        };
        FileOutConfig cEntity = new FileOutConfig("/templates" + templates + "/entity.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return entityPath + "/" + tableInfo.getEntityName() + StringPool.DOT_JAVA;
            }
        };
        FileOutConfig cService = new FileOutConfig("/templates" + templates + "/templates_0_0_4/dao.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return servicePath + "/" + tableInfo.getEntityName() + "Ser" + StringPool.DOT_JAVA;
            }
        };
        FileOutConfig cServiceImpl = new FileOutConfig("/templates" + templates + "/templates_0_0_4/daoImpl.java.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return serviceImplPath + "/" + tableInfo.getEntityName() + "SerImpl" + StringPool.DOT_JAVA;
            }
        };
        List<FileOutConfig> fileOutConfigs = new ArrayList<>();
        fileOutConfigs.add(cMapperXml);
        fileOutConfigs.add(cDao);
        fileOutConfigs.add(cController);
        fileOutConfigs.add(cEntity);
        fileOutConfigs.add(cService);
        fileOutConfigs.add(cServiceImpl);
        generator.setCfg(
                new InjectionConfig() {
                    @Override
                    public void initMap() {
                        Map<String, Object> map = new HashMap<>();
                        map.put("basePackage", basePackage);
                        map.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm")));
                        this.setMap(map);
                    }
                }.setFileOutConfigList(fileOutConfigs)
        );
    }

    //模板配置
    private static void setTemplate() {
        generator.setTemplateEngine(new FreemarkerTemplateEngine());
        generator.setTemplate(
                new TemplateConfig()
                        .setController("/templates" + templates + "/controller.java")
                        .setService("/templates" + templates + "/service.java")
                        .setServiceImpl("/templates" + templates + "/serviceImpl.java")
                        .setXml("/templates" + templates + "/mapper.xml")
                        .setMapper("/templates" + templates + "/mapper.java")
                        .setEntity("/templates" + templates + "/entity.java")
        );
    }


    private static void yamlToJson(String s) {
//        Map<String, Object> loaded = null;
//        try {
//            FileInputStream fis = new FileInputStream(s + propertyPath);
//            Yaml yaml = new Yaml();
//            loaded = yaml.load(fis);
//        } catch (FileNotFoundException ex) {
//            ex.printStackTrace();
//        }
//        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(loaded);
//        JSONObject spring = (JSONObject) jsonObject.get("spring");
//        JSONObject datasource = (JSONObject) spring.get("datasource");
//        return datasource;
    }

    //去除表前缀
    private static String[] removeTablePrefix() {
        StringBuilder tablePrefix = new StringBuilder();
        for (int i = 0; i < 26; i++) {
            tablePrefix.append((char) ('a' + i)).append("_").append(",");
        }
        tablePrefix.append("0_").append(",");
        tablePrefix.append("_").append(",");
        return tablePrefix.toString().split(",");
    }

    //去除字段前缀
    private static String[] removeFilePrefix() {
        return "".split(",");
    }

    /**
     * 设置填充策略
     */
    protected static List<TableFill> getTableFills() {
        // 自定义需要填充的字段
        List<TableFill> tableFillList = new ArrayList<>();
        tableFillList.add(new TableFill("create_time", FieldFill.INSERT));
        tableFillList.add(new TableFill("update_time", FieldFill.INSERT_UPDATE));
        tableFillList.add(new TableFill("create_uid", FieldFill.INSERT));
        tableFillList.add(new TableFill("update_uid", FieldFill.INSERT_UPDATE));
        return tableFillList;
    }


}



